package ua.kharkov.khpi.tarasenko.bach.web.command.admin;

import java.sql.Connection;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import ua.kharkov.khpi.tarasenko.bach.core.Constant;
import ua.kharkov.khpi.tarasenko.bach.core.LocalizedResourceManager;
import ua.kharkov.khpi.tarasenko.bach.core.EShopException;
import ua.kharkov.khpi.tarasenko.bach.core.db.ConnectionManager;
import ua.kharkov.khpi.tarasenko.bach.core.db.DBUtils;
import ua.kharkov.khpi.tarasenko.bach.dao.core.DAOFactory;
import ua.kharkov.khpi.tarasenko.bach.dao.core.item.ItemDAO;
import ua.kharkov.khpi.tarasenko.bach.dao.core.item.ItemDTO;
import ua.kharkov.khpi.tarasenko.bach.web.command.Command;

public class CreateItemCommand extends Command {
	private static final Logger log = Logger.getLogger(CreateItemCommand.class);

	private LocalizedResourceManager LRManager;
	
	@Override
	public String execute(HttpServletRequest request,
			HttpServletResponse response) throws EShopException {

		String errorMessage = null;
		String forward = Constant.COMMAND_SHOW_ITEMS_LIST_BY_CATEGORY;

		// Create LocalizedResourceManager to get localized error messages
		LRManager = getLocalizedResourceManager(request);

		ItemDTO itemDTO = null;
		try {
			itemDTO = extractItemDTO(request);
			if (log.isTraceEnabled()) {
				log.trace("Got itemDTO from request:\n" + itemDTO);
			}

			// Add category id to show after creating
			forward += itemDTO.getCategory();

			// Validating item
			errorMessage = validateItem(itemDTO);
		} catch (NumberFormatException e) {
			errorMessage = LRManager.getMessage("error_message.incorrect_values");
		}

		if (errorMessage == null) {
			Connection conn = null;
			try {
				conn = ConnectionManager.getConnection();
				ItemDAO itemDAO = DAOFactory.getDAOFactory(
						DAOFactory.DAO_TYPE.MYSQL).getItemDAO(conn);

				int rowsAdded = itemDAO.addItem(itemDTO);

				// Item wasn't updated
				if (rowsAdded != 1) {
					errorMessage = LRManager.getMessage("error_message.item_not_created");
				} else {

					// Everything is ok, commit
					DBUtils.commitAndClose(conn);
				}
			} catch (EShopException e) {
				DBUtils.rollBackAndClose(conn);
				throw e;
			} finally {
				if (conn != null) {
					DBUtils.close(conn);
				}
			}
		}

		if (errorMessage != null) {
			forward = processError(request, errorMessage);
		}

		if (log.isDebugEnabled()) {
			log.debug("Forward to " + forward);
		}
		return forward;
	}

	/**
	 * Extracts item from request. After extracting item should be validated!
	 * TODO move out of this class and @see {@link UpdateItemCommand}
	 * 
	 * @param req
	 *            - request with item to extract.
	 * @return itemDTO - extracted item.
	 */
	private ItemDTO extractItemDTO(HttpServletRequest req) {
		ItemDTO itemDTO = new ItemDTO();

		String itemName = req.getParameter(Constant.ATTRIBUTE_ITEM_NAME);
		itemDTO.setName(itemName);

		String itemCategoryString = req
				.getParameter(Constant.ATTRIBUTE_ITEM_CATEGORY);
		if ((itemCategoryString == null) || (itemCategoryString.isEmpty())) {
			itemDTO.setId(-1);
		} else {
			itemDTO.setCategory(Integer.valueOf(itemCategoryString));
		}

		String itemQuantityString = req
				.getParameter(Constant.ATTRIBUTE_ITEM_QUANTITY);

		if ((itemQuantityString == null) || (itemQuantityString.isEmpty())) {
			itemDTO.setQuantity(-1);
		} else {
			itemDTO.setQuantity(Integer.valueOf(itemQuantityString));
		}

		String itemPriceString = req
				.getParameter(Constant.ATTRIBUTE_ITEM_PRICE);

		if ((itemPriceString == null) || (itemPriceString.isEmpty())) {
			itemDTO.setPrice(-1);
		} else {
			itemDTO.setPrice(Double.valueOf(itemPriceString));
		}

		String itemDescription = req
				.getParameter(Constant.ATTRIBUTE_ITEM_DESCRIPTION);
		itemDTO.setDescription(itemDescription);


		if (log.isTraceEnabled()) {
			StringBuilder builder = new StringBuilder();
			builder.append("Got parameters from request:\n");
			builder.append("\t");
			builder.append(Constant.ATTRIBUTE_ITEM_NAME);
			builder.append("=");
			builder.append(itemName);
			builder.append("\n");
			builder.append("\t");
			builder.append(Constant.ATTRIBUTE_ITEM_CATEGORY);
			builder.append("=");
			builder.append(itemCategoryString);
			builder.append("\n");
			builder.append("\t");
			builder.append(Constant.ATTRIBUTE_ITEM_QUANTITY);
			builder.append("=");
			builder.append(itemQuantityString);
			builder.append("\n");
			builder.append("\t");
			builder.append(Constant.ATTRIBUTE_ITEM_PRICE);
			builder.append("=");
			builder.append(itemPriceString);
			builder.append("\n");
			builder.append("\t");
			builder.append(Constant.ATTRIBUTE_ITEM_DESCRIPTION);
			builder.append(":\n");
			builder.append(itemDescription);

			log.trace(builder.toString());
		}
		
		return itemDTO;
	}

	/**
	 * Validated extracted item to create.
	 * 
	 * @param itemDTO
	 *            - item to validate.
	 * @return errorMessages - if item isn't valid; null - if item is valid.
	 */
	private String validateItem(ItemDTO itemDTO) {
		String errorMessages = "";

		if (itemDTO.getName().length() > 40) {
			errorMessages += LRManager.getMessage("error_message.item_name_to_long");
		}
		
		if (itemDTO.getCategory() == -1) {
			errorMessages += LRManager.getMessage("error_message.item_category_not_spec");
		}

		if (itemDTO.getQuantity() < 0) {
			errorMessages += LRManager.getMessage("error_message.item_quantity_not_spec");
		}

		if (itemDTO.getPrice() <= 0) {
			errorMessages += LRManager.getMessage("error_message.item_price_not_spec");
		}

		if (errorMessages.isEmpty()) {
			return null;
		} else {
			return errorMessages;
		}
	}
}
